#include "BusinessHandler.h"

BusinessHandler::BusinessHandler() {
    this->autorelease();
}

BusinessHandler::~BusinessHandler() {
}

void BusinessHandler::processSoundEvent(GameEvent* event) {
    SimpleAudioEngine* soundModel = SimpleAudioEngine::getInstance();
    switch (event->getEventCode()) {
        case EVT_LOGO_LAND: {
            int random = (rand() % CONFIG_MAX_RANDOM_MUSIC) + 1;
            char backgroundPath[200];
            sprintf(backgroundPath, MUSIC_GAME, random);
            soundModel->playBackgroundMusic(backgroundPath, true);
            break;
        }
        case EVT_JUMP: {
            soundModel->playEffect(EFFECT_JUMP);
            break;
        }
        case EVT_EQUIP: {
            Turtle* turtle = this->gameModel->getCurrentLevel()->getTurtle();
            if (turtle->getEquipment() == EQUIPMENT_NONE) {
                soundModel->playEffect(EFFECT_JUMP);
            } else {
                soundModel->playEffect(EFFECT_STEAL);
            }
            break;
        }
        case EVT_TURTLE_DIE: {
            soundModel->playEffect(EFFECT_DIE);
            break;
        }
        case EVT_TURTLE_PASS: {
            soundModel->playEffect(EFFECT_END);
            break;
        }
        case EVT_TURTLE_TELEPORT: {
            soundModel->playEffect(EFFECT_TELEPORT);
            break;
        }
        case EVT_NEW_BULLET: {
            soundModel->playEffect(EFFECT_SHOT);
            break;
        }
        case EVT_TURTLE_SLASH: {
            soundModel->playEffect(EFFECT_SLASH);
            break;
        }
        case EVT_LOGO_TOUCH_LAND: {
            soundModel->playEffect(EFFECT_STOMP);
            break;
        }
        case EVT_CLICK_BUTTON: {
            soundModel->playEffect(EFFECT_BUTTON);
            break;
        }
        case EVT_CHANGE_COMMAND: {
            soundModel->playEffect(EFFECT_COMMAND);
            break;
        }
        case EVT_SELECT: {
            soundModel->playEffect(EFFECT_SELECT);
            break;
        }
        case EVT_BULLET_HIT_HUMAN: {
            soundModel->playEffect(EFFECT_HIT_HUMAN);
            break;
        }
        case EVT_BULLET_HIT_LAND: {
            soundModel->playEffect(EFFECT_HIT_LAND);
            break;
        }
        case EVT_BULLET_HIT_MACHINE: {
            soundModel->playEffect(EFFECT_HIT_MACHINE);
            break;
        }
        case EVT_CRUSH: {
            soundModel->playEffect(EFFECT_CRUSH);
            break;
        }
        default: {
            break;
        }
    }
}

void BusinessHandler::processAds(GameEvent* event, Scene* scene) {
    switch (event->getEventCode()) {
        case EVT_START_GAME: {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
            Application::getInstance()->openURL(":showFullAds:");
#endif
            break;
        }
        case EVT_NEXT_MAP: {
            bool showFullAds = false;
            if (this->gameModel->getNumberDead() % 5 == 0 &&
                this->gameModel->getNumberDead() / 5 > 0) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
                Application::getInstance()->openURL(":showFullAds:");
#endif
                showFullAds = true;
            }
            
            if (showFullAds) {
                ((GameScene*) scene)->onPauseButtonClick(NULL);
            }
            break;
        }
        case EVT_REPLAY_MAP: {
            bool showFullAds = false;
            if (this->gameModel->getNumberDead() % 5 == 0 &&
                this->gameModel->getNumberDead() / 5 > 0) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
                Application::getInstance()->openURL(":showFullAds:");
#endif
                showFullAds = true;
            }
            
            if (showFullAds) {
                ((GameScene*) scene)->onPauseButtonClick(NULL);
            }
            break;
        }
        case EVT_QUIT_GAME: {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
            Application::getInstance()->openURL(":showFullAds:");
#endif
            break;
        }
        default: {
            break;
        }
    }
}

void BusinessHandler::processEvent(GameEvent* event) {
    switch (event->getEventCode()) {
        case EVT_START_GAME: {
            auto scene = new LevelScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->runWithScene(scene);
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            this->processAds(event, scene);
            
            break;
        }
        case EVT_BACK_LEVEL_FROM_LEVEL: {
            LevelScene* runningScene = (LevelScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new LevelScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            break;
        }
        case EVT_RESET_GAME: {
            this->gameModel->getSavedData()->setLevel(-1);
            this->gameModel->save();
            
            break;
        }
        case EVT_PLAY_GAME: {
            LevelScene* runningScene = (LevelScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new GameScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            DataEvent* dataEvent = (DataEvent*) event;
            this->gameModel->transit(1);
            this->gameModel->play(dataEvent->getArgumentInt());
            
            break;
        }
        case EVT_PAUSE_GAME: {
            this->gameModel->pause();
            break;
        }
        case EVT_RESUME_GAME: {
            this->gameModel->resume();
            break;
        }
        case EVT_QUIT_GAME: {
            GameScene* runningScene = (GameScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new LevelScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            this->gameModel->quit();
            break;
        }
        case EVT_EXIT_GAME: {
            Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
            exit(0);
#endif
            break;
        }
        case EVT_COMPLETED_GAME: {
            GameScene* runningScene = (GameScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new LevelScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            this->gameModel->quit();
            this->gameModel->getSavedData()->setLevel(-1);
            this->gameModel->save();
            break;
        }
        case EVT_REPLAY_MAP: {
            GameScene* runningScene = (GameScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new GameScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            this->gameModel->transit(1);
            this->gameModel->replay();
            
            this->processAds(event, scene);
            
            break;
        }
        case EVT_NEXT_MAP: {
            GameScene* runningScene = (GameScene*) Director::getInstance()->getRunningScene();
            runningScene->disposeComponents();
            
            auto scene = new GameScene();
            this->getController()->listen(scene);
            
            Director::getInstance()->replaceScene(TransitionFade::create(1, scene));
            Director::getInstance()->getScheduler()->scheduleUpdate(scene, SCHEDULE_SCENE, false);
            
            this->gameModel->transit(1);
            this->gameModel->next();
            this->gameModel->updateLevel();
            this->gameModel->save();
            
            this->processAds(event, scene);
            
            break;
        }
        case EVT_CHANGE_MUSIC: {
            DataEvent* dataEvent = (DataEvent*) event;
            this->gameModel->getSavedData()->setMusicOn(dataEvent->getArgumentInt() == 1 ? true : false);
            this->gameModel->save();
            break;
        }
        case EVT_CHANGE_EFFECT: {
            DataEvent* dataEvent = (DataEvent*) event;
            this->gameModel->getSavedData()->setEffectOn(dataEvent->getArgumentInt() == 1 ? true : false);
            this->gameModel->save();
            break;
        }
        case EVT_GO_LEFT: {
            this->gameModel->getCurrentLevel()->getTurtle()->move(MOVE_LEFT);
            break;
        }
        case EVT_GO_RIGHT: {
            this->gameModel->getCurrentLevel()->getTurtle()->move(MOVE_RIGHT);
            break;
        }
        case EVT_GO_NONE: {
            this->gameModel->getCurrentLevel()->getTurtle()->move(MOVE_NONE);
            break;
        }
        case EVT_JUMP: {
            if (!this->gameModel->getCurrentLevel()->getTurtle()->jump()) {
                return;
            }
            break;
        }
        case EVT_EQUIP: {
            if (!this->gameModel->getCurrentLevel()->checkEquip()) {
                return;
            }
            break;
        }
        case EVT_FIRE: {
            this->gameModel->getCurrentLevel()->turtleFire();
            break;
        }
            
        default:
            break;
    }
    
    this->processSoundEvent(event);
}